#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# name: setup-users-config.sh
# description:  adds test users defined in metadata or default
#

# enable debug through -x and omit sensitive areas by turning off (set +x)
set -exuo pipefail

export HADOOP_CONF_DIR="/etc/hadoop/conf"

ROLE=$(/usr/share/google/get_metadata_value attributes/dataproc-role)
readonly USER_SETUP_LIST=$(/usr/share/google/get_metadata_value attributes/user-setup-list)
DEFAULT_USERS="jake,jarek,kamil,daniel,core-data-svc"

PURPOSE=$(/usr/share/google/get_metadata_value attributes/purpose)
if [[ "${PURPOSE}" == "ANALYTICS" ]] ; then
  CLUST_NAME="${ANALYTICS_CLUST}"
  CLUST_REALM="${ANALYTICS_REALM}"
fi

if [[ "${PURPOSE}" == "METASTORE" ]] ; then
  CLUST_NAME="${METASTORE_CLUST}"
  CLUST_REALM="${METASTORE_REALM}"
fi
HOSTNAME="${CLUST_NAME}-m"

# Setup unix user account for example users
#  required to be created on all hadoop nodes when kerberized for application
#  tasks to run as end user account
function create_unix_accounts() {
  local users=${USER_SETUP_LIST}
  if [[ -z "${users}" ]]; then
    users=${DEFAULT_USERS}
  fi
  for i in ${users//,/ }; do
    adduser --disabled-password --gecos "" $i
  done
}

# add hadoop paths for user
function config_hadoop_users() {
  local users=${USER_SETUP_LIST}
  if [[ -z "${users}" ]]; then
    users=${DEFAULT_USERS}
  fi
  for i in ${users//,/ }; do
    add_hdfs_user_dir $i
  done
}

function add_hdfs_user_dir() {
  local user=$1

  kinit -kt /etc/security/keytab/hdfs.service.keytab "hdfs/${HOSTNAME}.${DOMAIN}@${CLUST_REALM}"
  hadoop fs -mkdir "/user/${user}"
  hadoop fs -chown "${user}:${user}" "/user/${user}"
  hadoop fs -chmod 700 "/user/${user}"
}

# add basic hdfs configs for security
function config_hdfs_site() {
  echo "Setting properties in hdfs-site.xml."
  set_property_hdfs_site 'dfs.permissions.enabled' "true"
  set_property_hdfs_site 'dfs.namenode.acls.enabled' "true"
}

# setup helper
function set_env_helpers() {
  local dataproc_dir='/usr/local/share/google/dataproc'
  # shellcheck source=/dev/null
  source ${dataproc_dir}/bdutil/bdutil_helpers.sh
}

# encrypt keytab
function g_decrypt_secret() {
  local keytab_file=$1

  gcloud kms decrypt --ciphertext-file "${keytab_file}.encrypted" \
    --plaintext-file "${keytab_file}" --key "${KMS_KEY_URI}"
}

function download_setup_keytabs() {
  local users=${USER_SETUP_LIST}
  if [[ -z "${users}" ]]; then
    users=${DEFAULT_USERS}
  fi
  for i in ${users//,/ }; do

    # setup keytab for non-human service account
    if [[ "${i}" == *"svc" ]]; then
      setup_keytab "$i"
    fi
  done
}

function setup_keytab() {
  local username=$1
  local keytab_file=${username}.keytab
  g_cp "${CLIENT_RESOURCES_PATH}/${keytab_file}.encrypted" /etc/security/keytab/
  g_decrypt_secret "/etc/security/keytab/${keytab_file}"
  rm "/etc/security/keytab/${keytab_file}.encrypted"

  chown "${username}:${username}" "/etc/security/keytab/${keytab_file}"
  chmod 400 "/etc/security/keytab/${keytab_file}"
}

function log_and_fail() {
  echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: ERROR $*" >&2
  return 1
}

# gcs copy
function g_cp() {
  CMD="gsutil cp ${1} ${2}"
  ${CMD} || log_and_fail "Unable to execute ${CMD}"
}

function main() {
  set_env_helpers
  config_hdfs_site
  create_unix_accounts

  if [[ "${ROLE}" == 'Master' ]]; then
    config_hadoop_users
    download_setup_keytabs

    systemctl restart hadoop-hdfs-namenode
    systemctl restart hadoop-hdfs-secondarynamenode
  fi
}

main
